/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-12
 * V4.0
 */
package com.jphenix.share.tools;

import com.jphenix.standard.docs.ClassInfo;

import java.io.File;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;


/**
 * 隔离RAR支持包操作类
 * 如果项目中没有RAR支持包，则返回空值，并不报错
 * 
 * 在项目中把这个类单独复制出来使用
 * 
 * @author 马宝刚
 * 2009-6-11 下午04:52:43
 */
@ClassInfo({"2014-06-12 20:02","隔离RAR支持包操作类"})
public class RarArchiveInsulate {

	protected int rarSupport = -1; //是否支持rar 0不支持 1支持
	protected Class<?> rarSupportCls = null; //rar支持类
	protected Object rarSupportObj = null; //rar支持类实例
	protected String supportClassPath = null; //支持类路径
	
	
	/**
	 * 构造函数
	 * @author 马宝刚
	 */
	public RarArchiveInsulate() {
		super();
	}

	/**
	 * 设置支持类路径
	 * 马宝刚
	 * 2009-6-11 下午05:11:22
	 * @param supportClassPath 支持类路径
	 */
	public void setSupportClassPath(String supportClassPath) {
		this.supportClassPath = supportClassPath;
	}
	
	
	/**
	 * 是否支持Rar处理
	 * 马宝刚
	 * 2009-6-11 下午05:14:57
	 * @return true支持
	 */
	public boolean isSupportRar() {
		getRarSupportObj(); //初始化
		return rarSupport == 1;
	}
	
		/**
	 * 该文件是否为rar文件
	 * @author 刘虻
	 * @param file 文件
	 * @return 是否为rar文件
	 * 2008-9-1  下午06:33:37
	 */
	public static boolean isRarFile(File file) {
		try {
			//构造隔离RAR支持包操作类
			RarArchiveInsulate rarArchive = new RarArchiveInsulate();
			
			//获取rar支持类
			Class<?> rarCls = rarArchive.getRarSupportCls();
			if (rarCls==null) {
				return false;
			}
			//构建方法
			Method isRarFileMethod = 
				rarCls.getMethod("isRarFile", File.class);
			//执行方法
			Object res = isRarFileMethod.invoke(null, file);
			
			if (res==null) {
				return false;
			}
			return ((Boolean)res).booleanValue();
		}catch(Exception e) {}
		return false;
	}
	
	
	
	
	/**
	 * 该文件是否为rar文件
	 * @author 马宝刚
	 * @param filePath 文件路径
	 * @return 是否为rar文件
	 * 2008-9-10  下午02:54:29
	 */
	public static boolean isRarFile(String filePath) {
		return isRarFile(new File(filePath));
	}
	
	
	
	
	/**
	 * 设置文件
	 * @author 刘虻
	 * @param filePath 文件对象
	 * @throws Exception 执行发生异常
	 * 2008-8-16  下午08:50:40
	 */
	public void setFile(String filePath) throws Exception {
		//获取rar处理类
		Object rar = getRarSupportObj();
		if (rar==null) {
			return;
		}
		//构建方法
		Method setFileMethod = 
			rar.getClass().getMethod("setFile", String.class);
		//执行方法
		setFileMethod.invoke(rar, filePath);
	}
	
	
	
	/**
	 * 设置文件对象
	 * @author 刘虻
	 * @param file 文件对象
	 * @throws Exception 执行发生异常
	 * 2008-8-15  下午10:54:29
	 */
	public void setFile(File file) throws Exception {
		//获取rar处理类
		Object rar = getRarSupportObj();
		if (rar==null) {
			return;
		}
		//构建方法
		Method setFileMethod = 
			rar.getClass().getMethod("setFile", File.class);
		//执行方法
		setFileMethod.invoke(rar, file);
	}
	
	
	/**
	 * 是否不能够解压缩
	 * @author 刘虻
	 * @return 是否不能够解压缩
	 * 2008-8-15  下午11:09:47
	 */
	public boolean isEncrypted() {
		//获取rar处理类
		Object rar = getRarSupportObj();
		if (rar==null) {
			return true;
		}
		try {
			//构建方法
			Method setFileMethod = 
				rar.getClass().getMethod("isEncrypted");
			//执行方法
			Object res = setFileMethod.invoke(rar);
			if (res==null) {
				return true;
			}
			return ((Boolean)res).booleanValue();
		}catch(Exception e) {
			e.printStackTrace();
		}
		return true;
	}

	
	/**
	 * 设置是否启用日志
	 * @author 刘虻
	 * @param enabledLog 是否启用日志
	 * 2008-8-15  下午10:59:24
	 */
	public void setEnabledLog(boolean enabledLog) {
		try {
			
			//获取rar支持类
			Object rarObj = getRarSupportObj();
			if (rarObj==null) {
				return;
			}
			//构建方法
			Method isRarFileMethod = 
				rarObj.getClass().getMethod("setEnabledLog", boolean.class);
			//执行方法
			isRarFileMethod.invoke(rarObj, new Boolean(enabledLog));
		}catch(Exception e) {}
	}
	
	
	
	/**
	 * 设置输出根路径
	 * @author 刘虻
	 * @param extractPath 输出根路径
	 * 2008-8-15  下午11:27:58
	 */
	public void setExtractPath(String extractPath) {
		//获取rar处理类
		Object rar = getRarSupportObj();
		if (rar==null) {
			return;
		}
		try {
			//构建方法
			Method setFileMethod = 
				rar.getClass().getMethod("setExtractPath", String.class);
			//执行方法
			setFileMethod.invoke(rar, extractPath);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 获取文件路径序列
	 * 马宝刚
	 * 2009-6-11 下午06:11:56
	 * @return 文件路径序列
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
    public List<String> getFilePathList() {
		//获取rar处理类
		Object rar = getRarSupportObj();
		if (rar==null) {
			return new ArrayList<String>();
		}
		try {
			//构建方法
			Method setFileMethod = 
				rar.getClass().getMethod("getFilePathList");
			//执行方法
			List<String> res = (List)setFileMethod.invoke(rar,new Object[] {});
			if (res==null) {
				return new ArrayList<String>();
			}
			return res;
		}catch(Exception e) {
			e.printStackTrace();
		}
		return new ArrayList<String>();
	}
	
	
	/**
	 * 获取文件大小
	 * 马宝刚
	 * 2009-6-11 下午06:55:31
	 * @param filePath 文件相对路径
	 * @return 文件大小
	 * @throws Exception 执行发生异常
	 */
	public int getFileSize(String filePath) throws Exception {
		//获取rar处理类
		Object rar = getRarSupportObj();
		if (rar==null) {
			return 0;
		}
		//构建方法
		Method setFileMethod = 
			rar.getClass().getMethod("getFileSize", String.class);
		//执行方法
		Integer res = (Integer)setFileMethod.invoke(rar,new Object[] {filePath});
		if (res==null) {
			return 0;
		}
		return res.intValue();
	}
	
	
	/**
	 * 压缩包中是否包含此文件
	 * 马宝刚
	 * 2009-6-11 下午06:46:45
	 * @param filePath 文件相对路径
	 * @return true包含
	 */
	public boolean hasFile(String filePath) throws Exception {
		//获取rar处理类
		Object rar = getRarSupportObj();
		if (rar==null) {
			return false;
		}
		//构建方法
		Method setFileMethod = 
			rar.getClass().getMethod("hasFile", String.class);
		//执行方法
		Boolean res = (Boolean)setFileMethod.invoke(rar,new Object[] {filePath});
		if (res==null) {
			return false;
		}
		return res.booleanValue();
	}
	
	
	/**
	 * 解压缩指定文件
	 * 马宝刚
	 * 2009-6-11 下午06:42:34
	 * @param filePath 文件路径
	 * @param os 输出流
	 * @throws Exception 执行发生异常
	 */
	public void extractFile(String filePath,OutputStream os) throws Exception {
		//获取rar处理类
		Object rar = getRarSupportObj();
		if (rar==null) {
			return;
		}
		//构建方法
		Method setFileMethod = 
			rar.getClass().getMethod(
					"extractFile", String.class,OutputStream.class);
		//执行方法
		setFileMethod.invoke(rar, filePath,os);
	}
	
	
	/**
	 * 解压缩所有文件
	 * @author 刘虻
	 * @param outFileBasePath 指定文件保存根路径
	 * @throws Exception 执行发生异常
	 * 2008-8-16  下午08:43:22
	 */
	public void extractAllFile(String outFileBasePath) throws Exception {
		//获取rar处理类
		Object rar = getRarSupportObj();
		if (rar==null) {
			return;
		}
		//构建方法
		Method setFileMethod = 
			rar.getClass().getMethod(
					"extractAllFile", String.class);
		//执行方法
		setFileMethod.invoke(rar, outFileBasePath);
	}
	
	
	/**
	 * 设置输出信息接口
	 * 
	 * oei类必须实现以下方法
	 * 
	 * 
	 * 输出当前正在解压缩的文件路径
	 * void extractFile(String filePath);
	 * 
	 * @author 刘虻
	 * @param oei 输出信息接口
	 * 2008-8-16  下午09:35:54
	 */
	public void setOutExtractInfo(Object oei) {
		//获取rar处理类
		Object rar = getRarSupportObj();
		if (rar==null) {
			return;
		}
		try {
			//构建方法
			Method setFileMethod = 
				rar.getClass().getMethod("setOutExtractInfo", Object.class);
			//执行方法
			setFileMethod.invoke(rar, oei);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取支持类路径
	 * 马宝刚
	 * 2009-6-11 下午05:11:32
	 * @return 支持类路径
	 */
	public String getSupportClassPath() {
		if (supportClassPath==null) {
			supportClassPath = "de.innosystec.unrar.RarArchive";
		}
		return supportClassPath;
	}
	
	/**
	 * 获取RAR支持类
	 * 马宝刚
	 * 2009-6-11 下午05:05:24
	 * @return RAR支持类
	 */
	protected Class<?> getRarSupportCls() {
		if (rarSupport==-1) {
			try {
				rarSupportCls = Class.forName(getSupportClassPath());
				rarSupport = 1; //支持
			}catch(Exception e) {
				rarSupport = 0; //不支持
			}
		}
		return rarSupportCls;
	}
	
	
	/**
	 * 获取RAR支持类实例
	 * 马宝刚
	 * 2009-6-11 下午05:55:55
	 * @return RAR支持类实例
	 */
	protected Object getRarSupportObj() {
		if (rarSupportObj==null) {
			//获取支持类
			Class<?> rarCls = getRarSupportCls();
			if (rarCls==null) {
				return null;
			}
			try {
				rarSupportObj = rarCls.newInstance();
			}catch(Exception e) {
				e.printStackTrace();
				rarSupport = 0; //不支持
			}
		}
		return rarSupportObj;
	}
	
	
	
	/**
	 * 是否为文件
	 * 刘虻
	 * 2011-5-5 下午04:26:57
	 * @param filePath 文件相对路径
	 * @return true是
	 */
	public boolean isFile(String filePath) {
		//获取rar处理类
		Object rar = getRarSupportObj();
		if (rar==null) {
			return false;
		}
		try {
			//构建方法
			Method setFileMethod = 
				rar.getClass().getMethod("isFile", String.class);
			//执行方法
			Object res = setFileMethod.invoke(rar, filePath);
			if (res==null) {
				return false;
			}
			return ((Boolean)res).booleanValue();
		}catch(Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
	
	/**
	 * 关闭文件对象
	 * 刘虻
	 * 2011-5-5 下午05:22:53
	 */
	public void close() {
		//获取rar处理类
		Object rar = getRarSupportObj();
		if (rar==null) {
			return;
		}
		try {
			//构建方法
			Method setFileMethod = 
				rar.getClass().getMethod("close");
			//执行方法
			setFileMethod.invoke(rar);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}
